#include "BarWidget.h"
#include <QPainter>
#include <QWheelEvent>
#include <algorithm>
#include <unordered_set>

BarWidget::BarWidget(QWidget *p) : QWidget(p) {
    setMinimumSize(900, 450);
}

/* ---------- 接收一帧 ---------- */
void BarWidget::setData(const QVector<uint32_t> &v,
                        const QVector<int> &tag,
                        const SortStats &st) {
    m_vals = v;
    m_tag = tag;
    m_stats = st;

    if (m_autoScale && !m_vals.isEmpty()) {
        uint32_t mx = *std::max_element(m_vals.begin(), m_vals.end());
        m_scaleY = (mx == 0) ? 1.0 : (height() * 0.85) / double(mx);
    }
    update();
}

/* ---------- 绘 制 ---------- */
void BarWidget::paintEvent(QPaintEvent *) {
    QPainter qp(this);
    qp.fillRect(rect(), Qt::black);

    if (m_vals.isEmpty()) return;

    const int N = m_vals.size();
    const double bw = double(width()) / N;

    /* 柱形条 */
    for (int i = 0; i < N; ++i) {
        double h = m_vals[i] * m_scaleY;
        QRectF rc(i * bw - m_offset, height() - h, bw, h);

        int id = (i < m_tag.size()) ? m_tag[i] : -1;
        QColor col = (id >= 0)
                         ? kThreadColors[id % COLOR_COUNT]
                         : QColor::fromHsv(int(360.0 * m_vals[i] / (N + 1)), 255, 220);

        qp.fillRect(rc, col);
    }

    /* 统计信息 */
    qp.setPen(Qt::white);
    qp.drawText(10, 18,
                QString("Compare %1   Swap %2   Time %3 ms")
                .arg(m_stats.compare)
                .arg(m_stats.swap)
                .arg(m_stats.ms, 0, 'f', 2));

    /* ---------- 线程颜色图例 ---------- */
    std::unordered_set<int> seen;
    int x0 = 10, y0 = 30, box = 12, pad = 6;
    for (int id: m_tag) {
        if (id < 0 || seen.count(id)) continue;
        seen.insert(id);

        qp.fillRect(x0, y0, box, box, kThreadColors[id % COLOR_COUNT]);
        qp.drawText(x0 + box + 3, y0 + box, QString("T%1").arg(id));
        x0 += 50;
        if (x0 + 50 > width()) {
            y0 += box + pad;
            x0 = 10;
        }
        if (seen.size() >= COLOR_COUNT) break;
    }
}

/* ---------- 缩放 / 平移 ---------- */
void BarWidget::wheelEvent(QWheelEvent *e) {
    m_scaleY *= (e->angleDelta().y() > 0) ? 1.1 : 0.9;
    m_autoScale = false;
    update();
}

void BarWidget::mousePressEvent(QMouseEvent *e) {
    if (e->button() == Qt::LeftButton)
        m_lastPos = e->pos();
}

void BarWidget::mouseMoveEvent(QMouseEvent *e) {
    if (e->buttons() & Qt::LeftButton) {
        m_offset = std::fmod(m_offset + e->pos().x() - m_lastPos.x(), width());
        m_lastPos = e->pos();
        update();
    }
}
